﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using ANGFLib;

namespace ANGF
{
    public partial class FormEditModule : Form
    {
        private MyXmlDoc doc;
        public FormEditModule(MyXmlDoc doc)
        {
            XNamespace ns = ANGFLib.XmlNamespacesConstants.StdXmlNamespace;
            if (doc == null)
            {
                this.doc = new MyXmlDoc();
                this.doc.id = Guid.NewGuid().ToString();
                this.doc.name = "新しい拡張モジュール";
                var found = State.loadedModules.FirstOrDefault();
                this.doc.shareWorld = found == null ? null : found.Id;
                this.doc.versionInfo = new Version(1, 0, 0, 0);
                // 静的拡張モジュールである証としてのプレースホルダー
                this.doc.moduleEx = new XElement(ns + "moduleEx");
            }
            else
            {
                this.doc = doc;
            }
            InitializeComponent();
        }

        private void updateComboList()
        {
            this.comboBoxExpand.Items.Clear();
            foreach (var n in State.loadedModules)
            {
                // システムモジュールは無視される
                if (n.GetAngfRuntimeXml() == null) continue;
                this.comboBoxExpand.Items.Add(n.GetAngfRuntimeXml());
            }
            if (this.comboBoxExpand.Items.Count > 0) this.comboBoxExpand.SelectedIndex = 0;
        }

        private void updateStatus()
        {
            labelId.Text = this.doc.id;
            textBoxName.Text = this.doc.name;
            textBoxDescripton.Text = this.doc.description ?? "";
            textBoxVersion.Text = this.doc.versionInfo.ToString();
            for (int i = 0; i < comboBoxExpand.Items.Count; i++)
            {
                var m = (MyXmlDoc)comboBoxExpand.Items[i];
                if (m.id == this.doc.shareWorld)
                {
                    this.comboBoxExpand.SelectedIndex = i;
                    break;
                }
            }
        }

        private void updateRefer()
        {
            checkedListBoxAdditonalRefer.Items.Clear();
            foreach (var module in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (module.FullName.Contains("mscorlib")) continue;
                if (module.FullName.Contains("System.")) continue;
                if (module.FullName.Contains("System,")) continue;
                if (module.FullName.Contains("Microsoft.")) continue;
                if (module.FullName.Contains("ANGF")) continue;
                System.Reflection.AssemblyTitleAttribute asmttl = (System.Reflection.AssemblyTitleAttribute)Attribute.GetCustomAttribute(module, typeof(System.Reflection.AssemblyTitleAttribute));
                string assemblyTitle = asmttl != null ? asmttl.Title : module.FullName;
                if (assemblyTitle.Contains("vshost.exe")) continue;
                if (module.Location == "") continue;    // ignore dynamic generated module

                string name = Path.GetFileName(module.Location);
                int index = checkedListBoxAdditonalRefer.Items.Add(name);
                checkedListBoxAdditonalRefer.SetItemChecked(index, doc.AdditionalReferModuleNames.Select(c => c.ToLower()).Contains(name.ToLower()));
            }
        }

        private void FormEditNew_Load(object sender, EventArgs e)
        {
            updateComboList();
            updateStatus();
            updateRefer();
        }

        internal MyXmlDoc GetResult()
        {
            return doc;
        }

        private void buttonOK_Click(object sender, EventArgs e)
        {
            doc.name = this.textBoxName.Text;
            doc.description = this.textBoxDescripton.Text;

            if (comboBoxExpand.SelectedIndex >= 0)
            {
                var m = (MyXmlDoc)comboBoxExpand.Items[comboBoxExpand.SelectedIndex];
                doc.shareWorld = m.id;
            }
            else
            {
                MessageBox.Show(this, "拡張対象となるモジュールが選択されていません。",this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Version v;
            Version.TryParse(this.textBoxVersion.Text.Trim(), out v);
            doc.versionInfo = v;

            var list = new List<string>();
            for (int i = 0; i < checkedListBoxAdditonalRefer.CheckedItems.Count; i++)
            {
                list.Add( (string)checkedListBoxAdditonalRefer.CheckedItems[i]);
            }
            doc.AdditionalReferModuleNames = list.ToArray();

            this.DialogResult = DialogResult.OK;
            Close();
        }

        private string createItemString(int index)
        {
            if (index < 0) return "";
            MyXmlDoc n = (MyXmlDoc)this.comboBoxExpand.Items[index];
            if (n == null) return "";
            return n.name + "(" + n.id + ")";
        }

        private void comboBoxExpand_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            string s = createItemString(e.Index);
            e.Graphics.DrawString(s, e.Font, new SolidBrush(e.ForeColor), e.Bounds);
            e.DrawFocusRectangle();
        }
    }
}
